package collection.list.alibaba_p3c;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * XXX
 *
 * @author mengzhang6
 * @date 2018/12/27 9:39
 */
public class ListTest {

    @Test
    public void test() {

    }

    /**
     * 2. 【强制】  ArrayList 的 subList 结果不可强转成 ArrayList ，否则会抛出 ClassCastException
     * 异常，即 java.lang.ClassCastException: java.util.ArrayList$SubList cannot be cast to java.util.ArrayList
     * <p>
     * 说明： subList 返回的是  ArrayList 的内部类  SubList ，并不是  ArrayList ，而是
     * ArrayList 的一个视图，对于 SubList 子列表的所有操作最终会反映到原列表上。
     */
    @Test
    public void test2() {
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        list.add("fff");
        System.out.println(list);

        List<String> subList = list.subList(1, 3);
        System.out.println(subList);

        // ArrayList arrayList = (ArrayList) list.subList(1, 3);
        subList.add("dfg");
        System.out.println(list);

    }

    /**
     * 3. 【强制】在 subList 场景中，高度注意对原集合元素个数的修改，会导致子列表的遍历、增加、
     * 删除均会产生 ConcurrentModificationException 异常。
     */
    @Test
    public void test3() {
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        list.add("fff");
        System.out.println(list);

        List<String> subList = list.subList(1, 3);
        System.out.println(subList);
        for (String str : subList) {
            System.out.println(str);
        }

        list.add("ghj");

        for (String str : subList) {
            System.out.println(str);
        }
    }

    /**
     * 4. 【强制】使用集合转数组的方法，必须使用集合的 toArray(T[] array) ，传入的是类型完全
     * 一样的数组，大小就是 list . size() 。
     * 说明：使用 toArray 带参方法，入参分配的数组空间不够大时， toArray 方法内部将重新分配
     * 内存空间，并返回新数组地址 ； 如果数组元素大于实际所需，下标为 [ list . size() ] 的数组
     * 元素将被置为 null ，其它数组元素保持原值，因此最好将方法入参数组大小定义与集合元素
     * 个数一致。
     */
    @Test
    public void test4() {
        List<String> list = new ArrayList<String>(4);
        list.add("guan");
        list.add("bao");
        list.add("guan");
        list.add("bao");
        String[] array = new String[list.size() + 3];
        array = list.toArray(array);

        for (String str : array) {
            System.out.println(str);
        }

        /**
         * 反例：直接使用 toArray 无参方法存在问题，此方法返回值只能是 Object[] 类，若强转其它
         类型数组将出现 ClassCastException 错误。
         */
        String[] array2 = (String[]) list.toArray();
    }

    /**
     * 5. 【强制】使用工具类 Arrays . asList() 把数组转换成集合时，不能使用其修改集合相关的方
     * 法，它的 add / remove / clear 方法会抛出 UnsupportedOperationException 异常。
     * <p>
     * 说明： asList 的返回对象是一个 Arrays 内部类，并没有实现集合的修改方法。 Arrays . asList
     * 体现的是适配器模式，只是转换接口，后台的数据仍是数组。
     */
    @Test
    public void test5() {
        String[] strArray = {"eee", "fff", "ggg"};
        String[] strArray2 = new String[]{"aa", "bb", "cc", "dd"};

        List<String> stringList = Arrays.asList(strArray2);
        stringList.add("iii");
        System.out.println(stringList);

    }
}
